package com.meelive.ingkee.iknetwork.diagnose.util

import android.annotation.SuppressLint
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.net.ConnectivityManager
import android.net.Proxy
import android.net.wifi.WifiManager
import android.telephony.TelephonyManager
import android.text.TextUtils
import com.meelive.ingkee.base.utils.text.StringUtils
import com.meelive.ingkee.iknetwork.diagnose.DiagnoseProvider
import java.io.*
import java.net.Inet4Address
import java.net.NetworkInterface

@SuppressLint("DefaultLocale", "WifiManagerPotentialLeak", "MissingPermission")
object InKeNetworkDiagnoseUtil {

    const val NETWORKTYPE_INVALID = "UNKNOWN" // 没有网络

    const val NETWORKTYPE_WAP = "WAP" // wap网络

    const val NETWORKTYPE_WIFI = "WIFI" // wifi网络


    fun getNetWorkType(context: Context): String? {
        val mNetWorkType: String? = null
        val manager = context
                .getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager
                ?: return "ConnectivityManager not found"
        val networkInfo = manager.activeNetworkInfo
        if (networkInfo != null && networkInfo.isConnected) {
            val type = networkInfo.typeName
            if (type.equals("WIFI", ignoreCase = true)) {
                return NETWORKTYPE_WIFI
            } else if (type.equals("MOBILE", ignoreCase = true)) {
                val proxyHost = Proxy.getDefaultHost()
                return if (TextUtils.isEmpty(proxyHost)) {
                    mobileNetworkType(context)
                } else {
                    NETWORKTYPE_WAP
                }
            }
        } else {
            return NETWORKTYPE_INVALID
        }
        return null
    }

    /**
     * 判断网络是否连接
     */
    fun isNetworkConnected(): Boolean {
        val manager = DiagnoseProvider.getAppContext().getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager ?: return false
        val networkInfo = manager.activeNetworkInfo
        return !(networkInfo == null || !networkInfo.isAvailable)
    }


    /**
     * 获取本机IP(wifi)
     */
    fun getLocalIpByWifi(context: Context?): String? {
        if (context == null) {
            return ""
        }
        val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as? WifiManager
                ?: return "wifiManager not found"
        val wifiInfo = wifiManager.connectionInfo ?: return "wifiInfo not found"
        val ipAddress = wifiInfo.ipAddress
        return toIpAddress(ipAddress)
    }

    /**
     * 获取本机IP(2G/3G/4G)
     */
    fun getLocalIpBy3G(): String? {
        try {
            val en = NetworkInterface.getNetworkInterfaces()
            while (en.hasMoreElements()) {
                val intf = en.nextElement()
                val enumIpAddr = intf.inetAddresses
                while (enumIpAddr.hasMoreElements()) {
                    val inetAddress = enumIpAddr.nextElement()
                    if (!inetAddress.isLoopbackAddress
                            && inetAddress is Inet4Address) {
                        return inetAddress.getHostAddress().toString()
                    }
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return null
    }

    /**
     * wifi状态下获取网关
     */
    fun pingGateWayInWifi(context: Context): String? {
        var gateWay: String? = null
        val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as? WifiManager
                ?: return "wifiManager not found"
        val dhcpInfo = wifiManager.dhcpInfo
        if (dhcpInfo != null) {
            val tmp = dhcpInfo.gateway
            gateWay = toIpAddress(tmp)
        }
        return gateWay
    }

    private fun toIpAddress(tmp: Int): String? {
        return String.format("%d.%d.%d.%d", tmp and 0xff, tmp shr 8 and 0xff,
                tmp shr 16 and 0xff, tmp shr 24 and 0xff)
    }

    /**
     * 获取本地DNS
     */
    fun getLocalDns(dns: String): String? {
        var process: Process? = null
        var str: String? = ""
        var reader: BufferedReader? = null
        try {
            process = Runtime.getRuntime().exec("getprop net.$dns")
            reader = BufferedReader(InputStreamReader(
                    process.inputStream))
            var line: String? = null
            while (reader.readLine().also { line = it } != null) {
                str += line
            }
            reader.close()
            process.waitFor()
        } catch (e: IOException) {
            e.printStackTrace()
        } catch (e: InterruptedException) {
            e.printStackTrace()
        } finally {
            try {
                reader?.close()
                process!!.destroy()
            } catch (e: Exception) {
            }
        }
        return str!!.trim { it <= ' ' }
    }

    private fun mobileNetworkType(context: Context): String? {
        val telephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as? TelephonyManager ?: return "TM==null"
        return when (telephonyManager.networkType) {
            TelephonyManager.NETWORK_TYPE_1xRTT -> "2G"
            TelephonyManager.NETWORK_TYPE_CDMA -> "2G"
            TelephonyManager.NETWORK_TYPE_EDGE -> "2G"
            TelephonyManager.NETWORK_TYPE_EVDO_0 -> "3G"
            TelephonyManager.NETWORK_TYPE_EVDO_A -> "3G"
            TelephonyManager.NETWORK_TYPE_GPRS -> "2G"
            TelephonyManager.NETWORK_TYPE_HSDPA -> "3G"
            TelephonyManager.NETWORK_TYPE_HSPA -> "3G"
            TelephonyManager.NETWORK_TYPE_HSUPA -> "3G"
            TelephonyManager.NETWORK_TYPE_UMTS -> "3G"
            TelephonyManager.NETWORK_TYPE_EHRPD -> "3G"
            TelephonyManager.NETWORK_TYPE_EVDO_B -> "3G"
            TelephonyManager.NETWORK_TYPE_HSPAP -> "3G"
            TelephonyManager.NETWORK_TYPE_IDEN -> "2G"
            TelephonyManager.NETWORK_TYPE_LTE -> "4G"
            TelephonyManager.NETWORK_TYPE_UNKNOWN -> "UNKNOWN"
            else -> "4G"
        }
    }


    /**
     * 存储日志文件
     */
    fun copyDiagnoseToFile(content: String) {
        if (StringUtils.isEmpty(content)) {
            return
        }
        val networkLogDir = DiagnoseProvider.getAppContext().filesDir.absolutePath + "/IKMonitor/NetworkDiagnose"
        val networkLogRoot = File(networkLogDir)
        if (!networkLogRoot.exists()) {
            networkLogRoot.mkdirs()
        }
        val fileName = "$networkLogDir/inke_network_diagnosis_android.txt"
        var output: FileOutputStream? = null
        try {
            output = FileOutputStream(fileName)
            output.write(content.toByteArray())
        } catch (e: IOException) {
            e.printStackTrace()
        } finally {
            try {
                output?.close()
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
    }

    /**
     * 将字符串添加到剪贴板
     */
    fun addToClipboardWithoutToast(msg: String?) {
        val clip = ClipData.newPlainText("simple text", msg)
        (DiagnoseProvider.getAppContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager).setPrimaryClip(clip)
    }
}